# -*- coding:utf-8 -*-

########################################################
# Date: 05/04/11                                       #
# Auteurs: Rigaut Maximilien & Gregoire Burnet         #
# Nom: Adem — Anima: Deus Ex Machina                   #
# Version: 0.1a                                        #
# Copyright 2011: Rigaut Maximilien & Gregoire Burnet  #
########################################################
#    This file is part of ADEM.
#
#    Adem is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Gomoku is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Adem. If not, see <http://www.gnu.org/licenses/>.
########################################################
# LICENCE                                              #
########################################################

print """
+------------------------------------------------------------------+
| Adem Copyright (C) 2010 Rigaut Maximilien & Gregoire Burnet      |
| Ce programme est livré SANS AUCUNE GARANTIE.                     |
| Ceci est un logiciel libre et vous êtes invité à le redistribuer |
| suivant certaines conditions.                                    |
+------------------------------------------------------------------+
"""
#======================+
#  Modules             |
#----------------------+

import os,sys
import hashlib,pickle

nomApp="Adem"
nomComplet="Anima Deus Ex Machina"
extention='.anima'
#- - - - - - - - - - - -
cwd=os.getcwd()
sys.path.append(cwd+'/Modules')
sys.path.append(cwd+'/Personnages')
#- - - - - - - - - - - -

#======================+
#  Sous-Modules        |
#----------------------+

import characterClass

#======================+
#  Classes             |
#----------------------+

class character(object):
	"""Personnage Anima"""
	def __init__(self,nom):
		"Initialisation du personnage"
		self.skills={}
		self.aptitudes={}
		self.name=light_crypt(nom)
		self.Name=nom
		self.info={}
		self.level=0
		self.armors=[]
		self.weapons=[]
		for skill in skills:
			self.skills[skill]=0
		for aptitude in aptitudes:
			self.aptitudes[aptitude]=0
		self.__dict__ ={'nom':self.name,'Nom':self.Name,'skills':self.skills,'aptitudes':self.aptitudes,'info':self.info,'level':self.level,'armors':self.armors,'weapons':self.weapons}
	def __str__(self):
		"Affichage light du personnage"
		return '('+self.name+'): '+self.Name
	def lpr(self):
		print "+====================="
		print "| Nom :",self.Name
		print "| Niveau :",self.level
		if len(self.weapons)>0:
			print "+====================="
			print "| Armes"
			print "+---------------------"
			for arme in self.weapons:
				if arme in armes:
					armes[arme].lpr()
		if len(self.armors)>0:
			print "+====================="
			print "| Armures"
			print "+---------------------"
			for armor in self.armors:
				if armor in armures:
					armures[armor].lpr()
		print "+====================="
		print "| Characteristiques "
		print "+---------------------"
		for apt,val in self.aptitudes.iteritems():
			print "|",apt,':',val
		for name,group in skills_groups.iteritems():
			print "+---------------------"
			print '|',skills_groups_names[name]
			print "+ - - - - - - - - - -"
			for comp in group:
				print '|',comp,':',self.skills[comp]
	def initialise(self):
		#print "Pour un resultat aleatoire taper ?d<nombre de faces>+<valeur>"
		# - Infos
		self.Name=raw_input("Nom (Pour l'affichage): ")
		self.level=secure(int,'Niveau du personnage: ')
		# - Armures
		if len(armures.keys())>0: print 'Armures Existantes',armures.keys()
		n_armor=secure(Armor,"Armure (Nom d'armure existante, tapez 'new' pour en créer une ou 'none' pour aucune): ",sortie=['new','none'],dictionnaire=armures)
		if n_armor=='new':
			n_armor=new(str,"Nom court pour l'armure (ne peut etre changé): ")
			n_armor=Armor(n_armor)
			n_armor.initialise()
		if n_armor!='none': self.armors+=[n_armor.name]
		if len(armes.keys())>0: print 'Armes Existantes',armures.keys()
		# - Armes
		n_weapon=secure(Weapon,"Arme (Nom d'arme existante, tapez 'new' pour en créer une ou 'none' pour aucune): ",sortie=['new','none'],dictionnaire=armes)
		if n_weapon=='new':
			n_weapon=new(str,"Nom court pour l'arme (ne peut etre changé): ")
			n_weapon=Weapon(n_weapon)
			n_weapon.initialise()
		if n_weapon!='none': self.weapons+=[n_weapon.name]
		# - Caracs
		for carac in self.aptitudes.keys():
			self.aptitudes[carac]=secure(int,str(carac)+': ')
		 
class Weapon(object):
	"A standart anima Weapon"
	def __init__(self,nom):
		self.name=nom
		self.vals={}
		self.__dict__={'name':self.name,'vals':self.vals}
	def initialise(self):
		self.Name=raw_input("Nom (Pour l'affichage): ")
		self.vals['att']=secure(int,"Valeur d'Attaque: ")
		self.vals['par']=secure(int,'Valeur de Parade: ')
		self.vals['bas']=secure(int,'Base de Dégâts : ')
		#self.vals['deg']=secure(int,'Valeur de Dégats: ')
		self.vals['spe']=secure(int,'Valeur de Spécial ? ')
		self.vals['sol']=secure(int,'Valeur de Solidité: ')
		self.vals['fra']=secure(int,'Valeur de Fracassement: ')
		self.vals['pre']=secure(int,'Valeur de Présence: ')
		self.vals['mod1']=secure(str,"Mode d'utilisation 1: ")
		self.vals['mod2']=secure(str,"Mode d'utilisation 1: ")
	def change(self,valeur,new_valeur):
		valeur=valeur.lower()[:3]
		if valeur=='nom':
			self.now=new_valeur
		if valeur in self.vals.keys():
			if type(new_valeur)==int:
				self.vals[valeur]=new_valeur
		else:
			print "Cette valeur n'existe pas"
	def lpr(self):
		print "+ - - - - - - - - - -"
		print '| Nom:',self.Name
		print "+ - - - - - - - - - -"
		for cha,val in self.vals.iteritems():
			print '|',cha.upper(),':',val	
class Armor(object):
	"A standart Anima Armor"
	def __init__(self,nom):
		global armures
		self.Name=nom
		self.name=light_crypt(nom)
		self.vals={}
		armures[nom]=self
		self.__dict__={'name':self.name,'vals':self.vals,'Name':self.Name}
	def initialise(self):
		self.Name=raw_input("Nom (Pour l'affichage): ")
		self.vals['sol']=secure(int,'Valeur de solidité: ')
		self.vals['pre']=secure(int,'Valeur de presence? ')
		self.vals['spe']=secure(int,'Valeur de spetial? ')
		self.vals['req']=secure(int,'Valeur requise? ')
		self.vals['tra']=secure(int,'IP contre Tranchant: ')
		self.vals['per']=secure(int,'IP contre Perforant: ')
		self.vals['cha']=secure(int,'IP contre Chaleur: ')
		self.vals['ele']=secure(int,'IP contre Elementaire? ')
		self.vals['fro']=secure(int,'IP contre Froid: ')
		self.vals['ene']=secure(int,'IP contre Energie: ')
	def change(self,valeur,new_valeur):
		valeur=valeur.lower()[:3]
		if valeur=='nom':
			self.now=new_valeur
		if valeur in self.vals.keys():
			if type(new_valeur)==int:
				self.vals[valeur]=new_valeur
		else:
			print "Cette valeur n'existe pas"
	def lpr(self):
		print "+ - - - - - - - - - -"
		print '| Nom:',self.Name
		print "+ - - - - - - - - - -"
		for cha,val in self.vals.iteritems():
			print '|',cha.upper(),':',val		
#----------------------+
# Initialisation       |
#- - - - - - - - - - - +

#- - - - - - - - - - - +
# Competences et Characteristiques
Acrobatiques=['Acrobaties','Athletisme','Equitation','Escalade','Natation','Saut']
Vitales=['Impasibilite','P. De Force','Res. Douleur']
Intelectuelles=['Animaux','Estimation','E. Magique','Herborist','Histoire','Medecine','Memoris','Navigation','Occultisme','Science']
Sociales=['Commandement','Intimidation','Persuasion','Style']
Clandestines=['Camouflage','Crochetage','Deguise','Discretion','Larcin','Pieges','Poisons']
Creatives=['Art','Danse','Forge','H. Manuelle','Musique']

#- - - - - - - - - - - +
# Dictionnaires
aptitudes=['AGI','CON','DEX','FOR','INT','PER','POU','VOL']
skills=Acrobatiques+Vitales+Intelectuelles+Sociales+Clandestines+Creatives
skills_groups={'Acr':Acrobatiques,'Vit':Vitales,'Int':Intelectuelles,'Soc':Sociales,'Cla':Clandestines,'Cre':Creatives}
skills_groups_names={'Acr':'Acrobatiques','Vit':'Vitales','Int':'Intelectuelles','Soc':'Sociales','Cla':'Clandestines','Cre':'Creatives'}
interface={'notF':"%s n'existe pas",'help':"Tapez help pour obtenir la liste des commandes disponibles",'inc':'Type de données incorrect'}
#- - - - - - - - - - - +
# Variable In game

personnages={}
armures={}
armes={}

#- - - - - - - - - - - +
# Autres
debug=True
status=True

#======================+
# Fonctions internes   |
#----------------------+
def dp(text):
	if debug: print text

#- - - - - - - - - - - +
# Commandes in Game

def Help(arguments):
	"Afficher l'aide"
	dp("Arguments"+str(arguments))
	if len(arguments)==0:
		print 'Les commandes a votre disposition sont:'
		for comm,fonct in commandes.iteritems():
			print fonct.__doc__
	else:
		try:
			print eval(arguments[0]).__doc__
		except:
			print interface['notF']%("La commande"+str(arguments[0]))+'\n'+interface['help']
def Quit(arguments):
	"Quitter l'application"
	global status
	status=False

def Load(arguments):
	"load <objet> — Charge le peronnage ou l'armure ou l'arme <objet>"
	if len(arguments)!=1:
		print Load.__doc__
		return False
	path='./Sauvegardes/'+arguments[0]+extention
	if os.path.exists(path):
		temp=pickle.load(open(path,'r'))
		if type(temp)==Armor: armures[arguments[0]]=temp
		if type(temp)==character:
			personnages[arguments[0]]=temp
			for arm in temp.armors:
				Load([arm])
		if type(temp)==Weapon: armes[arguments[0]]=temp
	else:
		print 'Fichier introuvable'
	
def Loadall(arguments):
	"loadall — Charge tous les objets/personnages disponibles"
	for fil in os.listdir('./Sauvegardes/'):
		if extention in fil:
			Load([fil[:-len(extention)]])
			
def Save(arguments):
	"save <personnage> — Sauvegarde le personnage <personnage>"
	if len(arguments)!=1:
		print "Nombre d'arguments incorrects"
		return False
	if arguments[0] in personnages:
		dumpp=personnages[arguments[0]]
		for arm in dumpp.armors:
			Save([arm])
		for arm in dumpp.weapons:
			Save([arm])
	if arguments[0] in armures: dumpp=armures[arguments[0]]
	if arguments[0] in armes: dumpp=armes[arguments[0]]
	fi=open("./Sauvegardes/"+str(arguments[0])+extention,'w')
	pickle.Pickler(fi).dump(dumpp)
	fi.close()
	return True
		

def SaveAll(arguments):
	"saveall <personnages/armes/armures> — Sauvegarde tous les <personnages/armes/armures> en memoire"
	obj=personnages
	if len(arguments)==1:
		if arguments[0] in ['armes','weapons']:
			obj=armes
		if arguments[0] in ['armures','armors']:
			obj=armures
	for truc in obj.keys():
		Save([truc])
	return True
	
def New(arguments):
	"new <pj/armure/arme> — Crée une nouvelle instance d'arme/d'armure/de personnage"
	global personnages,armures
	if len(arguments)!=1:
		#print interface['inc']
		print "Commande Incorrecte"
		print New.__doc__
		return True
	if arguments[0] in ['personnage','perso','pj','pnj','pc','npc']:
		obj,dic,truc=character,personnages,'personnage'
	else:
		if arguments[0] in ['armure','armor']:
			obj,dic,truc=Armor,armures,'armure'
		else:
		#	return False
			if arguments[0] in ['weapon','arme']:
				obj,dic,truc=Weapon,armes,'arme'
	nom=new(str,'Entrez un nom court pour vôtre %s (ne peut etre changé): '%truc)
	dic[nom]=obj(nom)
	dic[nom].initialise()
	print "%s %s crée"%(truc.capitalize(),nom)
	#if debug: personnages[nom].lpr()

def Print(arguments):
	"print <objet> - Affiche les characteristiques de l'objet <objet>"
	if len(arguments)==1:
		if arguments[0] in personnages: personnages[arguments[0]].lpr()
		if arguments[0] in armures: armures[arguments[0]].lpr()
		if arguments[0] in armes: armes[arguments[0]].lpr()
	else:
		print Print.__doc__
	
def Delete(arguments):
	"delete <personnage> — Supprime le personnage <personnage>"
	pass

def Edit(arguments):
	"edit <personnage/armure/arme> <attribut> — Edite l'attribut du personnage ou de l'armure ou de l'arme passé en argument"
	if len(arguments)!=2: return False
	if exist(arguments[0]):
		if arguments[0] in armures: obj=armures[arguments[0]]
		if arguments[0] in personnages: obj=personnages[arguments[0]]
		if arguments[0] in armes: obj=armes[arguments[0]]
		if arguments[1] in ['armes','arme','weapon','weapons']: arguments[1]='weapons'
		if arguments[1] in ['armors','armures','armure','armor']: arguments[1]='armors'
		if arguments[1] in ['name','nom']: arguments[1]=arguments[1].capitalize()
		if arguments[1] in obj.__dict__:
		    typ=type(obj.__dict__[arguments[1]])
		    if typ==int or typ==str:
		    	text=secure(typ,"Entrez une nouvelle valeur pour %s: "%arguments[1])
		    	#print text,obj.__dict__[arguments[1]],arguments[1]
		    	obj.__dict__[arguments[1]]=text
		    	return True
		    if typ==dict:
		    	for ke in obj.__dict__[arguments[1]]:
		    		obj.__dict__[arguments[1]][ke]=secure(type(obj.__dict__[arguments[1]][ke]),"Entrez une nouvelle valeur pour %s: "%str(ke))
		    	return True
		    if typ==list:
		    	if arguments[1]=='armors':
		    		print "Entrez les armures du personnage ('exit' pour sortir)"
		    		obj.__dict__[arguments[1]]=newlist(Armor,armures,"Entrez une nouvelle armure : ",sortie=['exit'])
		    	if arguments[1]=='weapons':
		    		print "Entrez les armes du personnage ('exit' pour sortir)"
		    		obj.__dict__[arguments[1]]=newlist(Weapon,armes,"Entrez une nouvelle armure : ",sortie=['exit'])
		for table in obj.__dict__:
			if type(obj.__dict__[table])==dict:
				#print "Dico loaded",obj.__dict__[table]
				if arguments[1] in obj.__dict__[table].keys():
					obj.__dict__[table][arguments[1]]=secure(type(obj.__dict__[table][arguments[1]]),"Entrez une nouvelle valeur pour %s: "%str(arguments[1]))
					return True
		    
	else:
		print "L'objet n'existe pas"
		return False			
					
def Fight(arguments):
	"fight <personnage1>[:<weapon number> optionnel] <personnage2>[:<weapon number> optionnel] — <personnage1> Attaque <personnage2>"
	pass

def Use(arguments):
	"use <personnage> <competence> — Utilise la competece ou le domaine de competence cité"
	pass


#- - - - - - - - - - - +
# Commandes Systeme

	
def analyse(prompt):
	prompt=prompt.split(' ')
	prompt[0]=prompt[0].lower()
	if prompt[0] in commandes:
		res=commandes[prompt[0]](prompt[1:])
		if res==False: print "Commande Incorrecte"
	else:
		print interface['notF']%('La commande '+str(prompt[0]))+'\n'+interface['help']

def secure(N_type,question,text=False,sortie=[],dictionnaire=False):
	"Verifie que la réponse a la question soit de type N_type, on peut répondre <sortie> pour sortir (False)"
	#dp(dictionnaire)
	while True:
		if text==False:text=raw_input(question)#.lower()
		if text in sortie: return text
		try:
			#text=light_crypt(text)
			if N_type==int: text=eval(text)
			if dictionnaire!=False:
				#dp("Dico loaded"+str(dictionnaire))
				if text in dictionnaire.keys():
					text=dictionnaire[text]
				else:
					print interface['inc']
					text=False
			if type(text)==N_type: return text
		except:
			print interface['inc']
			text=False

def light_crypt(nom):
	for i,j in [(' ','_'),("'",'-'),('"','-'),('é','e'),('è','e'),('ë','e'),('ê','e'),('à','a'),('ñ','n')]:
		nom=nom.replace(i,j)
	return nom

def exist(nom):
	return nom in armures or nom in armes or nom in personnages

def new(N_Type,question,texte=False,dictionnair=False):
	while texte==False:
		texte=light_crypt(secure(N_Type,question,text=texte,dictionnaire=dictionnair))
		if not exist(texte):
			return texte
		print "Déjà existant"
		texte=False

def newlist(N_Type,dictionnary,question,sortie=['exit']):
	ret=[]
	while True:
		text=secure(N_Type,question,sortie=['exit'],dictionnaire=dictionnary)
		if text in sortie: return ret
		ret+=[text.name]
#- - - - - - - - - - - +
# Liste des Commandes
commandes={'help':Help,'quit':Quit,'load':Load,'save':Save,'saveall':SaveAll,'new':New,'edit':Edit,'fight':Fight,'use':Use,'print':Print,'loadall':Loadall	}


#======================+
# Programme principal  |
#----------------------+
prompt,entry='Adem$ ',''
#personnages["Max"]=character("Max")
#Save(['Max'])

while status:
	entry=raw_input(prompt)
	analyse(entry)
#----------------------+
# Initialisation       |
#- - - - - - - - - - - +
#langue={'Acrobaties':'Acrobaties','Athletisme':'Athlétisme','Equitation':'Équitation' 'Escalade' 'Natation' 'Saut' 'Vitales' 'Impasibilité' 'P. De Force' 'Rés. Douleur' 'Intelectuelles' 'Animaux' 'Estimation' 'E. Magique' 'Herborist' 'Histoire' 'Médecine' 'Mémoris' 'Navigation' 'Occultisme' 'Science' 'Sociales' 'Commandement' 'Intimidation' 'Persuasion' 'Style' 'Clandestines' 'Camouflage' 'Crochetage' 'Déguise' 'Discrétion' 'Larcin' 'Pièges' 'Poisons' 'Créatives' 'Art' 'Danse' 'Forge' 'H. Manuelle'  'Musique'}
